package com.rpg.world;

import java.io.InputStream;
import java.util.Random;

import com.rpg.battle.BattleView;
import com.rpg.Drawable_I;
import com.rpg.R;

import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.BitmapFactory;

public class WorldModel implements Drawable_I, View.OnTouchListener {

	private Activity activity;
	private WorldView worldView;
	private Sprite redGuy, skel;
	private Plot currentPlot;
	private Canvas myCanvas;
	private Random rand = new Random();
	private Dungeon currentDungeon;
	private Resources res;
	
	final int MOVE_SIZE = 24;
	
	public WorldModel(Activity act) {
		activity = act;
		worldView = new WorldView(this, activity);
		res = activity.getResources();
		
		redGuy = new Sprite(
				BitmapFactory.decodeResource(
						res, res.getIdentifier("com.rpg:drawable/red_guy", null, null)),
				30, 30);
		skel = new Sprite(BitmapFactory.decodeResource(res, R.drawable.sm_skeleton), 
				200, 200);
		
        activity.setContentView(worldView);
	}

	private void moveGuyOnce(int toX, int toY) {
		int dx = toX - redGuy.getX();
		int dy = toY - redGuy.getY();

		Resources res = activity.getResources();
		Log.d("WorldModel", 
				res.getResourceName(R.drawable.sm_skeleton) + "[" +
				res.getResourceTypeName(R.drawable.sm_skeleton) + "[" +
				res.getResourcePackageName(R.drawable.sm_skeleton));
		
		if (Math.abs(dx) > MOVE_SIZE/2 
				&& Math.abs(dx) > Math.abs(dy)
				&& (dx < 0 && redGuy.getX() > MOVE_SIZE) ||
				   (dx > 0 && redGuy.getX() < worldView.getWidth() - MOVE_SIZE)) {
			redGuy.changeX((dx < 0) ? -MOVE_SIZE : MOVE_SIZE); 
		}
		else if (Math.abs(dy) > MOVE_SIZE/2
				&& (dy < 0 && redGuy.getY() > MOVE_SIZE * 3 / 2) || 
				   (dy > 0 && redGuy.getY() < worldView.getHeight() - MOVE_SIZE * 3 / 2)) {
			redGuy.changeY((dy < 0) ? -MOVE_SIZE : MOVE_SIZE); 
		}

		if (rand.nextInt(100) < currentPlot.attackChance) {
			Log.d("WorldModel", "Should attack player now, chance: " + currentPlot.attackChance);
		}
		if (skel.overlaps(redGuy)) {
			final BattleView battleView = new BattleView(activity);
			battleView.post(new Runnable(){
				public void run() {
					battleView.invalidate();
				};
			});
		}
		else if (currentPlot.hitDungeon(redGuy)) {
			currentDungeon = new Dungeon(activity, redGuy);
	        activity.setContentView(currentDungeon);
			currentDungeon.post(new Runnable(){
				public void run() {
					currentDungeon.invalidate();
				};
			});
		}
		else {
			boolean redrawAll = true;
			if (myCanvas != null) {
				Log.d("", "guy y " + redGuy.getY());
				Log.d("", "view height " + worldView.getHeight());
				
				if (redGuy.getX() < MOVE_SIZE
						&& currentPlot.hasPlotToThe(PlotDir.WEST)) {
					// going west
					currentPlot = currentPlot.getNeighbor(PlotDir.WEST);
					redGuy.setX(worldView.getWidth() - MOVE_SIZE * 2);
					Log.d("WorldModel.moveGuyOnce", "went west");
				}
				else if (redGuy.getX() > worldView.getWidth() - MOVE_SIZE
						&& currentPlot.hasPlotToThe(PlotDir.EAST)) {
					// going east
					currentPlot = currentPlot.getNeighbor(PlotDir.EAST);
					redGuy.setX(MOVE_SIZE);
					Log.d("WorldModel.moveGuyOnce", "went east");
				}
				else if (redGuy.getY() < MOVE_SIZE * 3 / 2
						&& currentPlot.hasPlotToThe(PlotDir.NORTH)) {
					// going north
					currentPlot = currentPlot.getNeighbor(PlotDir.NORTH);
					redGuy.setY(worldView.getHeight() - MOVE_SIZE * 5 / 2);
					Log.d("WorldModel.moveGuyOnce", "went north");
				}
				else if (redGuy.getY() > worldView.getHeight() - MOVE_SIZE * 3 / 2
						&& currentPlot.hasPlotToThe(PlotDir.SOUTH)) {
					// going south
					currentPlot = currentPlot.getNeighbor(PlotDir.SOUTH);
					redGuy.setY(MOVE_SIZE);
					Log.d("WorldModel.moveGuyOnce", "went south");
				}
				else {
					redrawAll = false;
				}
			}
			if (redrawAll) {
				worldView.post(new Runnable(){
					public void run() {
						worldView.invalidate();
					};
				});
			}
			else {
				worldView.post(new Runnable(){
					public void run() {
						worldView.invalidate(
								redGuy.getBoundsPlus(MOVE_SIZE));
					};
				});
			}
		}
	}
	
	public void onDraw(Canvas canvas) {
		Display disp = activity.getWindowManager().getDefaultDisplay();
		Log.d("WorldModel.onDraw", "width: " + disp.getWidth() + ", " + disp.getHeight());
		
		if (currentPlot == null) {
			try {
				InputStream is = activity.getAssets().open("mapdata");
				Plot.readPlots(is, res, worldView);
			}
			catch (Exception exn) {
				Log.e("WorldModel", "Couldn't read Plots", exn); 
			}
			currentPlot = Plot.getStartPlot();
		}

		myCanvas = canvas;
		currentPlot.onDraw(canvas);
		skel.onDraw(canvas);
		redGuy.onDraw(canvas);
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		moveGuyOnce((int)event.getRawX(), (int)event.getRawY());
		return false;
	}

}
